<template>
  <div>
    <el-form :inline="true">
      <el-form-item>
        <el-input placeholder="角色名称" v-model="searchDto.name" auto-complete="off"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="searchByName()">查询</el-button>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="onBtnAdd">新增</el-button>
      </el-form-item>
    </el-form>
    <!-- 角色列表 -->
    <custom-table
      :data="roleList"
      :columns="columns"
      :tableLoadingFlag="tableLoadingFlag"
      :operationColumn="operationColumn"
      :pagination="pagination">
    </custom-table>
    <!-- 角色新增，修改模态框 -->
    <el-dialog :title="dialogType ==='add'? '新增角色':'修改角色信息'" :visible.sync="dialogVisible"
               :close-on-click-modal="false" :before-close="beforeClose">
      <el-form :model="roleDto" :rules="roleRules" label-width="120px" ref="roleForm">
        <el-form-item label="角色名" prop="name">
          <el-input v-model="roleDto.name" auto-complete="off"></el-input>
        </el-form-item>
        <el-form-item label="显示名" prop="displayName">
          <el-input v-model="roleDto.displayName" auto-complete="off"></el-input>
        </el-form-item>
        <el-form-item label="角色类型" prop="type">
            <el-select v-model="roleDto.type" placeholder="请选择角色类型" @change="roleTypeChange()">
            <el-option
              v-for="item in roleTypeOptions"
              :key="item.id"
              :label="item.name"
              :value="item.id">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="所属办事处" prop="pointId" v-show="roleDto.type == 2">
          <el-select v-model="roleDto.pointId" placeholder="请选择所属办事处">
            <el-option
              v-for="item in officeList"
              :key="item.id"
              :label="item.name"
              :value="item.id">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="所属外包商" prop="pointId" v-show="roleDto.type == 3">
          <el-select v-model="roleDto.pointId" placeholder="请选择所属外包商">
            <el-option
              v-for="item in outsourcerList"
              :key="item.id"
              :label="item.company"
              :value="item.id">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="所属工厂" prop="pointId" v-show="roleDto.type == 4">
          <el-select v-model="roleDto.pointId" placeholder="请选择所属工厂">
            <el-option
              v-for="item in factoryList"
              :key="item.id"
              :label="item.name"
              :value="item.id">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="描述" prop="description">
          <el-input type="textarea" v-model="roleDto.description" :rows="2"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer">
        <el-button @click="cancel('roleForm')">取消</el-button>
        <el-button type="primary" @click="submit()">确定</el-button>
      </div>
    </el-dialog>
    <!-- 设置权限模态框 -->
    <el-dialog :close-on-click-modal="false" title="权限分配" :visible.sync="permissionsModelVisible" class="perm-assign"
               :before-close="closePermDialog" style="overflow-y: scroll;">
      <el-form ref="permForm" :model="permsForm">
        <el-collapse>
          <el-collapse-item v-for="p in permissions" :key="p.id" :title="p.name" :name="p.id">
            <!-- :indeterminate="isIndeterminate[p2.id]" -->
            <div v-for="p2 in p.children">
              <el-checkbox :indeterminate="isIndeterminate[p2.id]" v-model="checkAllP2[p2.id]"
                           @change="handleCheckAllChange(p2,checkAllP2[p2.id])">
                {{p2.name}}
              </el-checkbox>
              <br/>
              <el-checkbox-group v-if="p2.children.length>0" v-model="checkP2[p2.id]"
                                 @change="handleCheckedChange(p2,checkP2[p2.id])">
                <el-checkbox v-for="p3 in p2.children" :label="p3.id" :key="p3.id">{{p3.name}}</el-checkbox>
              </el-checkbox-group>
              <div style="margin: 15px 0;"></div>
            </div>
          </el-collapse-item>
        </el-collapse>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="closePermDialog">取 消</el-button>
        <el-button type="primary" @click="savePerms()">确 定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
  import CustomTable from '@/components/table/CustomTable'
  import {
    apiGetRoleList,
    apiGetRoleById,
    apiDelRole,
    apiAddRole,
    apiUpdRole,
    apiGetRolePerms,
    apiUpdRolePerms
  } from '@/api/basic/role'
  import {mapGetters} from 'vuex'
  import {parseTime} from '@/utils'
  import {apiGetOfficeList} from '@/api/basic/info/inside/office'
  import {apiGetFactoryList} from '@/api/basic/info/factory'
  import {apiGetOutsourcerList} from '@/api/basic/info/outsourcer'
  import {getRoleId, getUserId, getRoleType, getOfficeProvinceCode} from '@/utils/token'
  import {apiGetRoleTypeList} from '@/api/dictionary'

  export default {
    components: {
      CustomTable
    },
    created() {
      this.roleId = getRoleId()
      let listQuery = {
        pageNumber: this.pagination.currentPage,
        pageSize: this.pagination.pageSize
      }
      this.getRoleList(listQuery)
      let listQueryTotal = {
        pageNumber: 1,
        pageSize: 100
      }
      this.getOfficeList(listQueryTotal)
      this.getFactoryList(listQueryTotal)
      this.getOutsourcerList(listQueryTotal)
    },
    computed: {
      ...mapGetters(['menuList'])
    },
    data() {
      return {
        roleId: null,
        tableLoadingFlag: false,             // 角色列表相关数据
        columns: [
          {label: 'ID', name: 'id', width: '80', align: 'center'},
          {label: '角色名', name: 'name', width: '150', align: 'center'},
          {label: '显示名', name: 'displayName', width: '150', align: 'center'},
          {label: '角色类型', name: 'type', width: '150', align: 'center'},
          {label: '描述', name: 'description', align: 'center'},
          {label: '创建时间', name: 'createdTime', width: '160', align: 'center', formatter: this.formatTime}
        ],
        operationColumn: {
          width: '150',
          operations: [
            {name: '授权', callback: this.handlePrivate},
            {name: '编辑', callback: this.onBtnEdit},
            {name: '删除', callback: this.onBtnDel}
          ]
        },
        roleList: [],
        pagination: this.getData(this.getRoleList),
        dialogType: '',                        // 角色新增，修改模态框相关数据
        roleTypeOptions: this.getRoleTypeOption(),
        dialogVisible: false,
        permissionsModelVisible: false,
        isIndeterminate: [],
        checkAllP2: [],
        checkedP2: [],
        checkP2: [],
        roleDto: {
          roleId: undefined,
          userId: undefined,
          name: '',
          displayName: '',
          type: undefined,
          description: '',
          pointId: undefined
        },

        roleRules: {
          name: [{required: true, message: '请输入角色名称', trigger: 'blur'},
            {max: 20, message: '长度不得超过20字符', trigger: 'blur'}],
          displayName: [{required: true, message: '请输入角色显示名', trigger: 'blur'},
            {max: 20, message: '长度不得超过20字符', trigger: 'blur'}],
          type: [{type: 'number', required: true, message: '请选择角色类型', trigger: 'change'}],
          pointId: [{
            validator: (rule, value, callback) => {
              if (this.roleDto.type === 2 || this.roleDto.type === 3 || this.roleDto.type === 4) {
                if (this.roleDto.pointId === '') {
                  callback(new Error('请选择类型'))
                } else {
                  callback()
                }
              } else {
                callback()
              }
            },
            trigger: 'blur'
          }],
          description: [{max: 50, message: '长度不得超过50个字符', trigger: 'blur'}]
        },
        userPerms: [],
        defaultProps: {
          children: 'children',
          label: 'name'
        },
        oldPermissions: [],
        permissions: [],
        permCheckList: [],
        permsForm: {
          id: '',
          roleId: '',
          perm: [],
          parentId: []
        },
        officeList: [],
        factoryList: [],
        outsourcerList: [],
        searchDto: {
          name: ''
        }
      }
    },
    methods: {
      inArray(needle, array) {
        for (var i in array) {
          if (needle === array[i]) {
            return true
          }
        }
        return false
      },
      handleCheckAllChange(p2, val) {
        var p2Id = p2.id
        var parentId = p2.parentId
        // 无TRUE 有Flase
        var data = []
        // var parentIds = []
        p2.children.forEach(function (p3) {
          data.push(p3.id)
        })
        this.checkP2[p2Id] = val ? data : []
        // 使得取消状态能够被执行
        if (val) {
          this.checkedP2[parentId][p2Id] = this.checkP2[p2Id]
        } else {
          var newArr = []
          for (let i in this.checkedP2[parentId]) {
            if (p2Id !== parseInt(i)) {
              // 一级菜单下如果有二级菜单，则保存
              if (this.checkedP2[parentId][i].length > 0) {
                newArr[i] = this.checkedP2[parentId][i]
              } else {
                newArr[i] = []
              }
            }
          }
          this.checkedP2[parentId] = newArr
        }
        this.isIndeterminate[p2Id] = false
      },

      handleCheckedChange(p2, val) {
        var p2Id = p2.id
        // var that = this
        var parentId = p2.parentId
        var checkedCount = val.length
        var allLength = p2.children.length
        // 取消联动状态，二级菜单选中，一级菜单也默认选中
        // this.checkAllP2[p2Id] = checkedCount === allLength
        // this.isIndeterminate[p2Id] = checkedCount < allLength && checkedCount > 0
        this.checkedP2[parentId][p2Id] = val
      },

      formatTime(row, column, cellValue) {
        return parseTime(cellValue)
      },

      getRoleList (listQuery) {
        // 切换分页时判断是否已有查询条件
        if (listQuery.name === undefined) {
          listQuery.name = this.searchDto.name
        }
        this.tableLoadingFlag = true
        apiGetRoleList(listQuery).then(response => {
          this.roleList = response.data
          this.pagination.totalRecords = response.totalRecords
          this.tableLoadingFlag = false
        }).catch(() => {
          this.tableLoadingFlag = false
        })
      },
      onBtnAdd() {
        this.roleDto = {
          roleId: undefined,
          userId: undefined,
          name: '',
          displayName: '',
          type: undefined,
          description: '',
          pointId: undefined
        }
        this.dialogType = 'add'
        this.dialogVisible = true
      },
      onBtnEdit(row) {
        apiGetRoleById(row.id).then(response => {
          let type = parseInt(response.data.type)
          this.roleDto = {
            roleId: row.id,
            userId: getUserId(),
            name: response.data.name,
            displayName: response.data.displayName,
            type: type,
            description: response.data.description,
            pointId: response.data.pointId
          }
          this.dialogType = 'edit'
          this.dialogVisible = true
        })
      },
      onBtnDel(row) {
        this.$confirm('确定删除该角色？', '删除', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          apiDelRole(row.id).then(() => {
            this.$message({
              showClose: true,
              type: 'success',
              message: '删除成功!'
            })
            let listQuery = {}
            this.getRoleList(listQuery)
          })
        }).catch(() => {
        })
      },
      handlePrivate(row) {
        this.permissions = []
        this.oldPermissions = []
        this.checkP2 = []
        this.checkAllP2 = []
        this.checkedP2 = []
        this.isIndeterminate = []
        var h = () => {
          this.permsForm = {
            id: row.id, // 当前行ID
            roleId: this.roleId, // 当前登陆用户角色ID
            perm: [],
            parentId: []
          }
          this.permissionsModelVisible = true
        }
        if (this.permissions.length === 0) {
          var that = this
          apiGetRolePerms(this.roleId, 1).then(rsp => {
            this.permissions = rsp.data.children
            this.permissions.forEach(function (p) {
              if (p.children.length > 0) {
                p.children.forEach(function (p2) {
                  var parentId = p2.parentId
                  var p2Id = p2.id
                  that.checkP2[p2Id] = [] // 初始化使得checkP2[p2Id]每个属性都为各自的属性
                  // that.checkAllP2[p2Id] = []
                  that.checkedP2[parentId] = []
                  // that.isIndeterminate[p2Id] = undefined
                })
              }
            })
            if (this.permissions.length > 0) {
              apiGetRolePerms(row.id, 0).then(rsp => {
                // 将已经选中的列表再次放入当前列表中
                this.oldPermissions = rsp && rsp.data ? rsp.data.children : null
                if (this.oldPermissions) {
                  this.oldPermissions.forEach(function (p) {
                    if (p.children.length > 0) {
                      p.children.forEach(function (p2) {
                        var parentId = p2.parentId
                        var p2Id = p2.id
                        that.checkAllP2[p2Id] = true
                        // 保存一级菜单的选项
                        if (p2.children.length === 0) {
                          // that.checkP2[p2Id] = [p2Id]
                          if (that.checkedP2[parentId][p2.id] === undefined) {
                            that.checkedP2[parentId][p2.id] = []
                          } else {
                            that.checkedP2[parentId][p2.id].push(p2.id)
                          }
                        } else {
                          that.checkedP2[parentId][p2Id] = []
                        }
                        // 保存二级菜单选项
                        if (p2.children.length > 0) {
                          var newP3 = []
                          p2.children.forEach(function (p3) {
                            // that.checkAllP2[p3.id] = true
                            newP3.push(p3.id)
                          })
                          // that.isIndeterminate[p2Id] = false
                          that.checkP2[p2Id] = newP3
                          // 使得二级菜单的选项都被选中
                          newP3.forEach(function (p3Id) {
                            that.checkedP2[parentId][p2Id].push(p3Id)
                          })
                        }
                      })
                    }
                  })
                  h()
                }
              })
            }
          })

        } else {
          h()
        }
      },
      submit() {
        this.$refs['roleForm'].validate((valid) => {
          if (valid) {
            if (this.dialogType === 'add') {
              this.addSubmit()
            } else {
              this.updSubmit()
            }
          } else {
            return false
          }
        })
      },
      addSubmit() {
        this.roleDto.userId = getUserId()
        this.$refs['roleForm'].validate((valid) => {
          if (valid) {
            apiAddRole(this.roleDto).then(() => {
              this.$message({
                showClose: true,
                message: '新增成功',
                type: 'success'
              })
              this.cancel('roleForm')
              let listQuery = {}
              this.getRoleList(listQuery)
            })
          } else {
            return false
          }
        })
      },
      updSubmit() {
        this.dialogVisible = false
        apiUpdRole(this.roleDto).then(() => {
          this.$message({
            showClose: true,
            message: '更新成功',
            type: 'success'
          })
          this.cancel('roleForm')
          let listQuery = {}
          this.getRoleList(listQuery)
        })
      },
      savePerms: function () {
        var that = this
        var data = []
        var parentIds = []
        this.checkedP2.forEach(function (p1, p1Id) {
          if (p1.length > 0) {
            data.push(p1Id)
            parentIds.push(1)
            p1.forEach(function (p2, p2Id) {
              data.push(p2Id)
              parentIds.push(p1Id)
              if (p2.length > 0) {
                // 找到P2的parentId
                p2.forEach(function (p3) {
                  data.push(p3)
                  parentIds.push(p2Id)
                })
              }
            })
          }
        })
        this.permsForm.parentId = parentIds
        this.permsForm.perm = data
        var that = this
        var _data = {id: this.permsForm.id, roleId: this.permsForm.roleId, perm: data, parentId: parentIds}
        apiUpdRolePerms(_data).then(() => {
          this.$message({
            showClose: true,
            message: '设置权限成功',
            type: 'success',
            duration: 2000
          })
          that.permissionsModelVisible = false
          this.permissions = []
          this.oldPermissions = []
          this.permCheckList = []
        })
      },
      cancel(formName) {
        this.dialogVisible = false
        this.authDialogVisible = false
        if (undefined !== this.$refs[formName]) {
          this.$refs[formName].resetFields()
        }
      },
      getOfficeList(listQuery) {
        this.tableLoadingFlag = true
        // todo 设置办事处省份
        if (getRoleType() === '2') {
          listQuery.provinceCode = getOfficeProvinceCode()
        }
        apiGetOfficeList(listQuery).then(response => {
          this.officeList = response.data
        }).catch(() => {
        })
      },
      getFactoryList(listQuery) {
        this.listLoadingFlag = true
        apiGetFactoryList(listQuery).then(response => {
          let factoryList = []
          for (let i in response.data) {
            if (response.data[i].factoryType === '生产工厂') {
              factoryList.push(response.data[i])
            }
          }
          this.factoryList = factoryList
        }).catch(() => {
        })
      },
      getOutsourcerList(listQuery) {
        this.listLoadingFlag = true
        apiGetOutsourcerList(listQuery).then(response => {
          this.outsourcerList = response.data
        }).catch(() => {
        })
      },
      roleTypeChange() {
        this.roleDto.pointId = ''
      },
      searchByName() {
        apiGetRoleList(this.searchDto).then(response => {
          this.roleList = response.data
          this.pagination.totalRecords = response.totalRecords
          this.listLoadingFlag = false
        }).catch(() => {
          this.listLoadingFlag = false
        })
      },
      getRoleTypeOption(listQuery) {
        apiGetRoleTypeList(listQuery).then(response => {
          this.roleTypeOptions = response.data
        }).catch(() => {
        })
      },
      closePermDialog() {
        this.permissions = []
        this.oldPermissions = []
        this.permCheckList = []
        this.permissionsModelVisible = false
      },
      beforeClose() {
        this.$refs['roleForm'].resetFields()
        this.dialogVisible = false
      }
    }
  }
</script>
